/*
 * falsh_test.c
 *
 *  Created on: Jun 26, 2024
 *      Author: 18050
 */
#include "main.h"
#include "flash_test.h"
#include "fml_store.h"
#include "dri_flash_sst.h"
#include "string.h"

/**
 * @函数名	flash_test
 * @功能	    flash功能测试
 * @入口参数	无
 * @返回值	无
 */
void flash_test(void)
{
	uint8_t initBuff1[80] = {0};
	uint8_t initBuff2[64] = {0};
	uint8_t newDataBuff1[80] = {0};
	uint8_t newDataBuff2[64] = {0};
	uint8_t disPlayBuff1[80] = {0};
	uint8_t disPlayBuff2[64] = {0};
	PageHeader_t testHead = {0};
	FLASH_Err_t falshStatus = FLASH_NO_ERR;
	memset(initBuff1, 1, sizeof(initBuff1));
	memset(initBuff2, 2, sizeof(initBuff2));
	memset(newDataBuff1, 6, sizeof(newDataBuff1));
	memset(newDataBuff2, 6, sizeof(newDataBuff2));
	/* 1.创建FLASH实体 */
	FlashDevice_t Flash1 = {
			.flashName = "f1",
			.startAddr = 0x1F7000,
			.totalSize = 0x4000,
			.minEraseSize = 0x1000,
			.minOperateSize = 0x1000,
			.initFlashCB = initFlash,
			.readFlashCB = readFlash,
			.eraseFlashCB = eraseFlash,
			.writeFlashCB = writeFlash};
	/* 2.检查FLASH实体合法性 */
 	FML_FlashDeviceRegister(&Flash1);
 	/* 3.创建分区数组 */
 	Partition_t Flash1PartBuff[10] = {0};
	/* 4.创建分区实体，并赋值给分区数组 */
	Partition_t Parition1 = {
			.partFlash = &Flash1,
			.partStartAddr = 0x1F7000,
			.partSize = 0x2000,
			.dataAddr = initBuff1,
			.dataSize = sizeof(initBuff1)};
	Partition_t Parition2 = {
			.partFlash = &Flash1,
			.partStartAddr = 0x1F9000,
			.partSize = 0x2000,
			.dataAddr = initBuff2,
			.dataSize = sizeof(initBuff2)};
	Flash1PartBuff[0] = Parition1;
	Flash1PartBuff[1] = Parition2;

 	/* 5.初始化分区并检查分区合法性 */
 	FML_PartInit(Flash1PartBuff, 2);
 	/* 6.重置分区，并向初始页写入数据 */
 	FML_PartReset(&Flash1PartBuff[0]);
 	FML_PartReset(&Flash1PartBuff[1]);
 	/* 7.读出初始化数据 */
	falshStatus = FML_PartRead(Flash1PartBuff[0], disPlayBuff1);
	falshStatus = FML_PartRead(Flash1PartBuff[1], disPlayBuff2);
	/* 8.读出页表头,该步直接调用FLASH硬件层函数，方便调试 */
	readFlash(Parition1.partStartAddr, (uint8_t* )&testHead, sizeof(testHead));
	readFlash(Parition2.partStartAddr, (uint8_t* )&testHead, sizeof(testHead));
	/* 9.向分区内写入数据 */
	falshStatus = FML_PartWrite(Flash1PartBuff[0], newDataBuff1);	// 写入新数据
	falshStatus = FML_PartWrite(Flash1PartBuff[1], newDataBuff2);	// 写入新数据
	/* 10.读出新写入的数据 */
	falshStatus = FML_PartRead(Flash1PartBuff[0], disPlayBuff1);
	falshStatus = FML_PartRead(Flash1PartBuff[1], disPlayBuff2);
	/* 11.读出页表头,该步直接调用FLASH硬件层函数，方便调试 */
	readFlash(Parition1.partStartAddr, (uint8_t* )&testHead, sizeof(testHead));
	readFlash(Parition2.partStartAddr, (uint8_t* )&testHead, sizeof(testHead));
}
/**
 * @函数名	   initFlash
 * @功能	   初始化不同的FLASH芯片
 * @入口参数   无
 * @返回值	    无
 */
void initFlash(void)
{
	DRI_Flash_Init();
}

/**
 * @函数名	readFlash
 * @功能	    调用底层驱动函数从FLASH中读取数据
 * @入口参数	addr：读取数据地址 buf：数据缓冲区 size:读取数据的大小
 * @返回值	无
 */
void readFlash(uint32_t addr, uint8_t *buf, uint16_t size)
{
	DRI_Flash_ReadBuffer(buf, addr, size);
}

/**
 * @函数名	writeFlash
 * @功能	    调用底层驱动函数向FLASH中写入数据
 * @入口参数	addr：写入数据地址 buf：数据缓冲区 size:写入数据的大小
 * @返回值	无
 */
void writeFlash(uint32_t addr, uint8_t *buf, uint16_t size)
{
	DRI_Flash_WriteBuffer(buf, addr, size);
}

/**
 * @函数名   	eraseFlash
 * @功能	    调用底层驱动函数擦除数据
 * @入口参数	addr：擦除数据始地址  size:擦除数据的大小（MIN_ECRASE_SIZE的整数倍）
 * @返回值	无
 */
void eraseFlash(uint32_t addr, uint16_t size)
{
	uint16_t sectorNum = 0;
	if (size % MIN_ECRASE_SIZE != 0)
	{
		return;
	}
	sectorNum = size / MIN_ECRASE_SIZE;
	for (uint16_t i = 0; i < sectorNum; ++i) {
		// 计算当前扇区的地址
		uint32_t sectorAddr = addr + i * 4096;

		// 擦除当前4KB扇区
		DRI_Flash_Erase_4KByte(sectorAddr);
	}
}



